package com.sailboard.iot.opm.service.aliyun;

import com.alibaba.fastjson.JSON;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.aliyuncs.sts.model.v20150401.AssumeRoleRequest;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;
import com.sailboard.iot.opm.common.JsonResult;
import com.sailboard.iot.opm.common.ResultCode;
import com.sailboard.iot.opm.config.AliyunConfig;
import com.sailboard.iot.opm.framework.RedisManager;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class OssService {

    private static org.slf4j.Logger logger = LoggerFactory.getLogger(OssService.class);

    private static final String REGION_CN_HANGZHOU = "cn-hangzhou";
    private static final String STS_API_VERSION = "2015-04-01";
//    private static final String accessKeyId = "B7Otoy7pG6N8bPuA";
//    private static final String accessKeySecret = "dbeXPQufqtTetuOhA4mFGisoNVETtL";
//    private static final  String roleArn = "acs:ram::1960336514521050:role/aliyunosstokengeneratorrole";
//    private static final String roleSessionName = "external-username";
//    private static final long durationSeconds = 3600;
    private static final String policy =
    "{\n" +
    "    \"Statement\": [\n" +
    "    {\n" +
    "        \"Action\": [\n" +
    "        \"oss:*\"\n" +
    "            ],\n" +
    "        \"Effect\": \"Allow\",\n" +
    "            \"Resource\": [\"acs:oss:*:*:*\"]\n" +
    "    }\n" +
    "    ],\n" +
    "    \"Version\": \"1\"\n" +
    "}";

//            "{\n" +
//            "   \"Statement\": [\n" +
//            "       { \n" +
//            "           \"Action\": [\n" +
//            "               \"oss:GetObject\",\n" +
//            "               \"oss:PutObject\",\n" +
//            "               \"oss:DeleteObject\",\n" +
//            "               \"oss:ListParts\",\n" +
//            "               \"oss:AbortMultipartUpload\",\n" +
//            "               \"oss:ListObjects\"\n" +
//            "           ],\n" +
//            "           \"Effect\": \"Allow\",\n" +
//            "               \"Resource\": [\"acs:oss:*:*:vii-img-test/*\", \"acs:oss:*:*:vii-img-test\"]\n" +
//            "       }\n" +
//            "   ],\n" +
//            "   \"Version\": \"1\"\n" +
//            "}";

    private static final String STS_REDIS_INFO = "OSS_STS_INFO";


    @Resource
    RedisManager redisManager;
    @Resource
    AliyunConfig aliyunConfig;

    protected AssumeRoleResponse assumeRole(String accessKeyId, String accessKeySecret, String roleArn,
                                            String roleSessionName, String policy, ProtocolType protocolType,
                                            long durationSeconds) throws ClientException {
        try {
            // 创建一个 Aliyun Acs Client, 用于发起 OpenAPI 请求
            IClientProfile profile = DefaultProfile.getProfile(REGION_CN_HANGZHOU, accessKeyId, accessKeySecret);
            DefaultAcsClient client = new DefaultAcsClient(profile);

            // 创建一个 AssumeRoleRequest 并设置请求参数
            final AssumeRoleRequest request = new AssumeRoleRequest();
            request.setVersion(STS_API_VERSION);
            request.setMethod(MethodType.POST);
            request.setProtocol(protocolType);

            request.setRoleArn(roleArn);
            request.setRoleSessionName(roleSessionName);
            request.setPolicy(policy);
            request.setDurationSeconds(durationSeconds);

            // 发起请求，并得到response
            final AssumeRoleResponse response = client.getAcsResponse(request);

            return response;
        } catch (ClientException e) {

            throw e;
        }
    }

    public JsonResult getStsTempAuthor() {
//        String data = ReadJson("./config.json");
//        System.out.println("用户输入url:" + data);
//        if (data.equals(""))
//        {
//            response(request, response, "./config.json is empty or not found");
//            return;
//        }
//        System.out.println(data);
//        JSONObject jsonObj  = JSONObject.fromObject(data);

        // 只有 RAM用户（子账号）才能调用 AssumeRole 接口
        // 阿里云主账号的AccessKeys不能用于发起AssumeRole请求
        // 请首先在RAM控制台创建一个RAM用户，并为这个用户创建AccessKeys
//        String accessKeyId = jsonObj.getString("AccessKeyID");
//        String accessKeySecret = jsonObj.getString("AccessKeySecret");

        // RoleArn 需要在 RAM 控制台上获取
//        String roleArn = jsonObj.getString("RoleArn");
//        long durationSeconds = jsonObj.getLong("TokenExpireTime");
//        String policy = ReadJson(jsonObj.getString("PolicyFile"));
        // RoleSessionName 是临时Token的会话名称，自己指定用于标识你的用户，主要用于审计，或者用于区分Token颁发给谁
        // 但是注意RoleSessionName的长度和规则，不要有空格，只能有'-' '_' 字母和数字等字符
        // 具体规则请参考API文档中的格式要求
//        String roleSessionName = "alice-001";
        // 此处必须为 HTTPS
//        ProtocolType protocolType = ProtocolType.HTTPS;

        Map map = redisManager.getHash(STS_REDIS_INFO);
        if(map == null || map.isEmpty()) {
            try {
                final AssumeRoleResponse stsResponse = assumeRole(
                        aliyunConfig.getOss().getAccessKeyId(),
                        aliyunConfig.getOss().getAccessKeySecret(),
                        aliyunConfig.getOss().getRoleArn(),
                        aliyunConfig.getOss().getRoleSessionName(),
                        policy, ProtocolType.HTTPS,
                        aliyunConfig.getOss().getDurationSeconds());

                Map<String, String> respMap = new LinkedHashMap<String, String>();
                respMap.put("status", "200");
                respMap.put("AccessKeyId", stsResponse.getCredentials().getAccessKeyId());
                respMap.put("AccessKeySecret", stsResponse.getCredentials().getAccessKeySecret());
                respMap.put("SecurityToken", stsResponse.getCredentials().getSecurityToken());
                respMap.put("Expiration", stsResponse.getCredentials().getExpiration());

                redisManager.setHash(STS_REDIS_INFO, (HashMap)respMap, (int) aliyunConfig.getOss().getDurationSeconds());
                logger.info("oss sts info get from 'Aliyun Acs Client' : {}", JSON.toJSONString(map));
                return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, respMap);
            } catch (ClientException e) {
                Map<String, String> respMap = new LinkedHashMap<String, String>();
                respMap.put("status", e.getErrCode());
                respMap.put("AccessKeyId", "");
                respMap.put("AccessKeySecret", "");
                respMap.put("SecurityToken", "");
                respMap.put("Expiration", "");
                logger.info("oss sts info get from 'Aliyun Acs Client' error: {}",  e.getErrMsg());
                return new JsonResult(ResultCode.ERROR_CODE, e.getErrMsg(), respMap);
            }
        } else {
            logger.info("oss sts info get from redis : {}", JSON.toJSONString(map));
            return new JsonResult(ResultCode.SUCCESS_CODE, ResultCode.SUCCESS_MSG, map);
        }
    }

}
